package concursos.ejb;

import java.security.SecureRandom;
import java.util.List;

import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import org.jboss.crypto.CryptoUtil;

import concursos.daos.UsuarioDAO;
import concursos.interfaces.UsuarioService;
import concursos.modelos.Usuario;

/**
 * Contém toda a regra de negócio relacionado ao usuário.
 * 
 * @author Felipe
 * @author Nayane
 * @author Rafael
 * 
 */
@Stateless
@LocalBean
public class UsuarioEjb implements UsuarioService {

	/**
	 * Servi�o respons�vel por persister as entidades.
	 */
	@PersistenceContext(unitName = "meusconcursosejb")
	private EntityManager manager;
	/**
	 * Objeto responsável por fazer a persistencia no banco de dados.
	 */
	private UsuarioDAO dao;

	/**
	 * Construtor padr�o.
	 */
	public UsuarioEjb() {
	}

	/**
	 * Realiza criptografia da senha do usuário, e o envia para o UsuarioDAO
	 * para ser salvo no banco.
	 * 
	 * @param usuario
	 *            Usuario
	 * @return usuario
	 */
	@Override
	public Usuario cadastrarUsuario(Usuario usuario) {
		SecureRandom rand = new SecureRandom();
		long num = rand.nextLong();
		String secString = (String.valueOf(num));
		usuario.setSecString(secString);
		String senha = usuario.getSenha();
		usuario.setSenha(encriptaSenha(senha, secString));

		return this.getDao().salvarUsuario(usuario);
	}

	/**
	 * Lista todos os usu�rios gravados no sistema.
	 * 
	 * @return lista de usuarios
	 */
	@Override
	public List<Usuario> listarUsuarios() {
		return this.getDao().listarUsuarios();
	}

	/**
	 * Busca usu�rio pelo id.
	 * 
	 * @param id
	 *            Identificador do usu�rio
	 * @return usuario
	 */
	@Override
	public Usuario buscaPorId(int id) {
		return this.getDao().buscaPorId(id);
	}

	/**
	 * Busca usu�rio pelo nome de usu�rio.
	 * 
	 * @param username
	 *            Nome de usu�rio
	 * @return usuario
	 */
	@Override
	public Usuario buscaPorUsername(String username) {
		return this.getDao().buscaPorUsername(username);
	}

	/**
	 * Busca usu�rio pelo c�digo de autoriza��o gerado para ele.
	 * 
	 * @param codigo
	 *            C�digo de Autoriza��o
	 * @return usuario
	 */
	@Override
	public Usuario buscarPorCodigoAutorizacao(String codigo) {
		return this.getDao().buscaPorCodigoAutorizacao(codigo);
	}

	/**
	 * Exclui usuário.
	 * 
	 * @param id
	 *            Identificador do usu�rio
	 */
	@Override
	public void excluirUsuario(int id) {
		this.getDao().excluirUsuario(id);
	}

	/**
	 * Realiza criptografia da senha do usuário com MD5.
	 * 
	 * @param senha
	 *            Senha do usuario
	 * @param secString
	 *            Codigo de segurança
	 * @return senhaCriptografada
	 */
	public static String encriptaSenha(String senha, String secString) {
		return CryptoUtil.createPasswordHash("MD5", "hex", null, null,
				senha.concat(secString));
	}

	/**
	 * Verifica se a senha informada é a mesma que está gravada no sistema.
	 * 
	 * @param senha
	 *            Senha informada do usuario
	 * @param secString
	 *            Codigo de seguran�a
	 * @param senhaDB
	 *            Senha criptografada no banco de dados
	 * @return
	 */
	public static boolean verficarSenha(String senha, String secString,
			String senhaDB) {
		return CryptoUtil.createPasswordHash("MD5", "hex", null, null,
				senha.concat(secString)).equals(senhaDB);
	}

	/**
	 * Altera a senha do usuário.
	 * 
	 * @param usuario
	 *            Usuario
	 * @return usuario
	 */
	@Override
	public Usuario alterarSenha(Usuario usuario) {
		SecureRandom rand = new SecureRandom();
		long num = rand.nextLong();
		String secString = (String.valueOf(num));
		usuario.setSecString(secString);
		String senha = usuario.getSenha();
		usuario.setSenha(encriptaSenha(senha, secString));
		return this.getDao().alterarSenha(usuario);

	}

	/**
	 * Retorna instância do objeto UsuarioDAO.
	 * 
	 * @return ConcursoDAO
	 */
	public UsuarioDAO getDao() {
		if (this.dao == null)
			this.dao = new UsuarioDAO(this.manager);
		return this.dao;
	}

}
